using System;
using System.Globalization;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;
using System.Reflection;
using Microsoft.Phone.Shell;
using Services;

using Utilities.Menu.UIElements;
using Services.Menu;
using Utilities.Menu;
using System.Collections.ObjectModel;
using TrenitaliaWP7.Resources;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Phone.Tasks;



namespace TrenitaliaWP7
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        private static bool CATCH_EXCEPTION = true;
        public static Rectangle trial_rectangle;
        public static string APP_ID = "75c4de83-134c-e011-854c-00237de2db9e";
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont font;
        StateManager StateManager;
        float alpha = 1;
        float sign = -1;
        Texture2D trialTexture, logo;
        Thread m_loadingThread;
        float m_loadDisplayTime;
        Rectangle texture_rectangle;
        DisplayOrientation prev_orientation;
        float alpha_logo;
        //bool first_time = true;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            StateManager = new StateManager(this, graphics);
            this.Services.AddService(typeof(AStateManager), StateManager);

            Strings.Culture = CultureInfo.CurrentCulture;
            //Selector.Culture = CultureInfo.CurrentCulture;
            //graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.SupportedOrientations = DisplayOrientation.Portrait | DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
 
            //StateManager.SelectIntroScreen();
            //StateManager.SelectMainMenu();
            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            graphics.SynchronizeWithVerticalRetrace = true;

            //StateManager.SelectMainMenu();
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            alpha = 0.0f;
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);


            //if (first_time)
            //{
            //    TouchPanel.EnabledGestures =
            //        GestureType.Tap;
            //    first_time = false;
            //}
            try
            {
                var occ = Storage.LoadUtilizations() + 1;
                new Thread(new ThreadStart(() =>
                {
                    Utilities.getHTML(Utilities.GetUtilizationUrl(occ, StateManager.isTrial),
                        (s) =>
                        {
                            Storage.DeleteUtilizations();
                        },
                        () =>
                        {
                            Storage.SaveUtilizations(occ);
                        });
                })).Start();
            }
            catch { }

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            // TODO: use this.Content to load your game content here

            trialTexture = Content.Load<Texture2D>("trial");
            font = Content.Load<SpriteFont>("Fonts/SegoeWP");
            logo = Content.Load<Texture2D>("Menu/vst_logo");
            m_loadingThread = new Thread(new ThreadStart(CreateAssets));
            m_loadingThread.Start();

            base.LoadContent();
        }
        private void CreateAssets()
        {
            StateManager.mainMenu = new MainMenu(this);
            new ResultMenu(this);
            new DetailsMenu(this);
        }
        protected override void Dispose(bool disposing)
        {
            this.Services.RemoveService(typeof(SpriteBatch));
            base.Dispose(disposing);
        }
        protected override void Update(GameTime gameTime)
        {
            // Monitor the loading thread

            try
            {

                if (m_loadingThread != null)
                {

                    if (prev_orientation != GraphicsDevice.PresentationParameters.DisplayOrientation)
                    {
                        prev_orientation = GraphicsDevice.PresentationParameters.DisplayOrientation;
                        if (prev_orientation == DisplayOrientation.LandscapeLeft || prev_orientation == DisplayOrientation.LandscapeRight)
                            SetLandScapeOrientation();
                        else
                            SetPortraitOrientation();
                    }

                    float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

                    alpha_logo += dt;
                    alpha_logo = Math.Min(1, alpha_logo);

                    //m_loadDisplayTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    m_loadDisplayTime += dt;
                    if (!m_loadingThread.Join(0) || (m_loadDisplayTime < 2f))
                    {
                        // Loading is still in progress, so sleep this thread for a while
                        Thread.Sleep(10);
                    }
                    else
                    {
                        // Loading thread has finished, so transition to your main menu screen
                        //m_screenStack.TransitionTo(Context.Screens.Main);
                        StateManager.SelectMainMenu();
                        m_loadingThread = null;
                    }
                }

                if (StateManager.isTrial)
                {
                    var dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
                    alpha += dt * sign / StateManager.TRIAL_VELOCITY;
                    if (alpha > 1)
                    {
                        alpha = 1;
                        sign = -1;
                    }
                    if (alpha < 0)
                    {
                        alpha = 0;
                        sign = 1;
                    }


                    //while (TouchPanel.IsGestureAvailable)
                    //{
                    //    GestureSample gs = TouchPanel.ReadGesture();
                    //    if (gs.GestureType == GestureType.Tap)
                    //    {
                    //        Rectangle r;
                    //        if (GraphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait)
                    //        {
                    //            r = new Rectangle(335, 0, 145, 141);

                    //        }
                    //        else
                    //        {
                    //            r = new Rectangle(655, 0, 145, 141);
                    //        }
                    //        if (RectContaintsVect(r, gs.Position))
                    //        {
                    //            MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();

                    //            marketplaceDetailTask.Show();
                    //        }
                    //    }
                        
                    //}
                }

                base.Update(gameTime);

            }
            catch (Exception e)
            {
                if (CATCH_EXCEPTION)
                    SendCrashReport(e.ToString());
                else
                    throw e;
                
            }


        }

        //private bool RectContaintsVect(Rectangle r, Vector2 v)
        //{
        //    return r.X <= v.X && r.Y <= v.Y && r.X + r.Width >= v.X && r.Y + r.Height >= v.Y;
        //}

        protected override void Draw(GameTime gameTime)
        {

            try
            {

                GraphicsDevice.Clear(Color.Black);
                if (m_loadingThread != null)
                {
                    spriteBatch.Begin();
                    spriteBatch.Draw(logo, texture_rectangle, Color.White * alpha_logo);
                    spriteBatch.End();
                }
                base.Draw(gameTime);
                if (StateManager.isTrial)
                {
                    spriteBatch.Begin();
                    var s = "TRIAL";
   
                    if (GraphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait)
                    {
                       trial_rectangle = new Rectangle(335, 0, 145, 141);

                    }
                    else
                    {
                        trial_rectangle = new Rectangle(655, 0, 145, 141);
                    }
                    var textPosition = new Vector2(0, 0);
                    var dimStringa = font.MeasureString(s);

                    textPosition.X = trial_rectangle.X + trial_rectangle.Width / 2 - dimStringa.X / 2;
                    textPosition.Y = trial_rectangle.Y + trial_rectangle.Height / 2 - dimStringa.Y / 2;

                    textPosition += font.MeasureString(s) / 2.0f + new Vector2(15, -5);
                    spriteBatch.Draw(trialTexture, trial_rectangle, Color.White * alpha);
                    spriteBatch.DrawString(font, s, textPosition, Color.White * alpha, MathHelper.ToRadians(45), font.MeasureString(s) / 2, 1, SpriteEffects.None, 1);
                    spriteBatch.End();
                }
            

            }
            catch (Exception e)
            {
                if (CATCH_EXCEPTION)
                    SendCrashReport(e.ToString());
                else
                    throw e;
                
            }

        }
        //internal void Draw()
        //{
        //    this.Draw(new GameTime(TimeSpan.Zero, TimeSpan.Zero));
        //}
        protected override void OnDeactivated(object sender, EventArgs args)
        {
            if (!StateManager.isTrial)
                StateManager.Deactivate();
            base.OnDeactivated(sender, args);
        }
        protected override void OnActivated(object sender, EventArgs args)
        {
            if (!StateManager.isTrial)
                StateManager.Activate();
            base.OnActivated(sender, args);
        }
        protected override void EndRun()
        {
            //Microsoft.Devices.VibrateController.Default.Stop();
            base.EndRun();
        }
        private void SetPortraitOrientation()
        {
            texture_rectangle = new Rectangle(GraphicsDevice.Viewport.Width / 2 - logo.Width / 2,
                GraphicsDevice.Viewport.Height / 2 - logo.Height / 2,
                logo.Width, logo.Height);
        }

        private void SetLandScapeOrientation()
        {
            texture_rectangle = new Rectangle(GraphicsDevice.Viewport.Width / 2 - logo.Width / 2,
                GraphicsDevice.Viewport.Height / 2 - logo.Height / 2,
                logo.Width, logo.Height);
        }

        string FixExceptionString(string s)
        {
            string s1 = s.Replace("\r", "").Replace("\n", "");
            return s1;
        }
        string FixDateString(string s)
        {
            string s1 = s.Replace('/', '-').Replace(':', '-').Replace(' ', '_');
            return s1;
        }
        void SendCrashReport(string s)
        {
            Components.Clear();
            var url = "http://fboscari.altervista.org/submit_string.php/?tab=CrashReports&applicazione=InformaTreni&dataora=" +
                FixDateString(DateTime.Now.ToString()) + "&stringa=" + FixExceptionString(s);
            Utilities.getHTML(url, GotHTML, ErrorHTML);

            
            Components.Add(new CrashMenu(this, url, s));            
        }
        void GotHTML(string s)
        {
            if(Components.Count==0)
                Exit();
        }
        void ErrorHTML()
        {
            if (Components.Count == 0)
                Exit();
        }
    }
}
